package pl.vanta.mjuzik;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.io.IOCase;
import org.apache.commons.io.filefilter.DirectoryFileFilter;
import org.apache.commons.io.filefilter.IOFileFilter;
import org.apache.commons.io.filefilter.OrFileFilter;
import org.apache.commons.io.filefilter.SuffixFileFilter;

import pl.vanta.mjuzik.formats.FormatFactory;
import pl.vanta.mjuzik.formats.IFileInfo;
import pl.vanta.mjuzik.formats.Format;
import pl.vanta.mjuzik.model.AudioFile;
import pl.vanta.mjuzik.playlists.IPlaylistFormat;
import pl.vanta.mjuzik.playlists.PlaylistFormatFactory;
import pl.vanta.utils.commons.FileUtils;
import pl.vanta.utils.gui.filters.GuiFileFilter;
import pl.vanta.utils.gui.filters.SaveFileFilter;

public class MusicUtils
{
	private MusicUtils()
	{
	}

	public static final AudioFile convert(File file, boolean checkFilePresenceOnLoad, boolean lazyPlaylistLoading)
	{
		AudioFile af = new AudioFile(file);

		if (!checkFilePresenceOnLoad)
		{
			if (!file.isFile() || !file.exists())
			{
				return null;
			}
		}

		if (!lazyPlaylistLoading)
		{
			FileInfo fi = FormatFactory.getInstance().getFileInfo(file);

			if (fi == null)
			{
				return null;
			}

			af.setFileInfo(fi);
		}

		af.setHash(createFileHash(file));

		return af;
	}

	private static String createFileHash(File file)
	{
		String hash = String.valueOf(file.length());

		return hash;
	}

	public static final List<AudioFile> convert(List<File> files, boolean checkFilePresenceOnLoad,
			boolean lazyPlaylistLoading)
	{
		List<AudioFile> audioFiles = new ArrayList<AudioFile>();

		for (File file : files)
		{
			AudioFile af = convert(file, checkFilePresenceOnLoad, lazyPlaylistLoading);

			if (af != null)
			{
				audioFiles.add(af);
			}
		}

		return audioFiles;
	}

	public static List<String> getSupportedPlaylistFilesExtensions()
	{
		List<String> extensions = new ArrayList<String>();

		List<IPlaylistFormat> playlistFormats = PlaylistFormatFactory.getInstance().getPlaylistFormats();
		for (IPlaylistFormat format : playlistFormats)
		{
			extensions.addAll(Arrays.asList(format.getExtensions()));
		}

		return extensions;
	}

	public static List<String> getSupportedMusicFilesExtensions()
	{
		List<String> extensions = new ArrayList<String>();

		List<FileFormat> formats = FormatFactory.getInstance().getFormats();
		for (FileFormat info : formats)
		{
			extensions.addAll(Arrays.asList(info.getExtensions()));
		}

		return extensions;
	}

	public static GuiFileFilter getMusicFilesFilter()
	{
		SuffixFileFilter sff = new SuffixFileFilter(getSupportedMusicFilesExtensions(), IOCase.INSENSITIVE);
		IOFileFilter dff = DirectoryFileFilter.DIRECTORY;

		GuiFileFilter gff = new GuiFileFilter(new OrFileFilter(sff, dff), "Music files");

		return gff;
	}

	public static List<GuiFileFilter> getPlaylistFilesFilters()
	{
		List<GuiFileFilter> filters = new ArrayList<GuiFileFilter>();

		List<IPlaylistFormat> playlistFormats = PlaylistFormatFactory.getInstance().getPlaylistFormats();

		for (IPlaylistFormat pf : playlistFormats)
		{
			SuffixFileFilter sff = new SuffixFileFilter(pf.getExtensions(), IOCase.INSENSITIVE);
			IOFileFilter dff = DirectoryFileFilter.DIRECTORY;

			SaveFileFilter saveff = new SaveFileFilter(new OrFileFilter(sff, dff), pf.getDescription(), pf
					.getExtensions()[0]);
			filters.add(saveff);
		}

		return filters;
	}

	public static GuiFileFilter getPlaylistFilesFilter()
	{
		SuffixFileFilter sff = new SuffixFileFilter(getSupportedPlaylistFilesExtensions(), IOCase.INSENSITIVE);
		IOFileFilter dff = DirectoryFileFilter.DIRECTORY;

		GuiFileFilter gff = new GuiFileFilter(new OrFileFilter(sff, dff), "Playlist files");

		return gff;
	}

	public static List<File> getAllFiles(List<File> files)
	{
		List<File> fileList = new ArrayList<File>();

		fileList.addAll(FileUtils.getAllFilesRecursive(files, getMusicFilesFilter()));

		return fileList;
	}

	public static List<File> getAllFilesFromPlaylists(File[] files)
	{
		List<File> fileList = new ArrayList<File>();

		List<File> playlists = FileUtils.getAllFilesRecursive(files, getPlaylistFilesFilter());

		for (File file : playlists)
		{
			fileList.addAll(PlaylistFormatFactory.getInstance().loadPlaylist(file));
		}

		return fileList;
	}
}